<template>
  <div ref="boxGeometryContainer"></div>
  <div id="info">Description</div>
</template>

<script lang="ts" setup>
import {onMounted, useTemplateRef} from "vue";
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
import {TextGeometry} from "three/examples/jsm/geometries/TextGeometry";
import {FontLoader} from "three/examples/jsm/loaders/FontLoader";

import {
  AxesHelper,
  BoxGeometry,
  BufferGeometry,
  Line,
  LineBasicMaterial,
  Mesh,
  MeshBasicMaterial,
  PerspectiveCamera,
  Scene,
  Vector3,
  WebGLRenderer
} from "three";

const boxGeometryContainerRef = useTemplateRef('boxGeometryContainer');

function createBoxGeometry() {
  const scene = new Scene();
  const axesHelper = new AxesHelper(150);
  // 坐标轴
  scene.add(axesHelper);
  const camera = new PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 3000);
  camera.position.set(5, 5, 5);
  camera.lookAt(0, 0, 0);
  const renderer = new WebGLRenderer();
  const geometry = new BoxGeometry(1, 1, 1);
  const material = new MeshBasicMaterial({
    color: 0x0000ff, //设置材质颜色
    transparent: true,//开启透明
    opacity: 0.5,//设置透明度
  });
  const cube = new Mesh(geometry, material);
  cube.position.set(1, 1, 1);
  scene.add(cube);
  renderer.setSize(window.innerWidth, window.innerHeight); //设置three.js渲染区域的尺寸(像素px)
  const animate = () => {
    if (cube) cube.rotation.x += 0.01;
    if (cube) cube.rotation.y += 0.01;
    if (renderer) renderer.render(scene, camera);
    requestAnimationFrame(animate);
  };
  boxGeometryContainerRef.value.appendChild(renderer.domElement);
  // 设置相机控件轨道控制器OrbitControls
  new OrbitControls(camera, renderer.domElement);
  // onresize 事件会在窗口被调整大小时发生
  window.onresize = function () {
    // 重置渲染器输出画布canvas尺寸
    renderer.setSize(window.innerWidth, window.innerHeight);
    // 全屏情况下：设置观察范围长宽比aspect为窗口宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
    // 但是不会每渲染一帧，就通过相机的属性计算投影矩阵(节约计算资源)
    // 如果相机的一些属性发生了变化，需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
    camera.updateProjectionMatrix();
  };
  animate();
}

function createLine() {
  const loader = new FontLoader();
  const renderer = new WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  boxGeometryContainerRef.value.appendChild(renderer.domElement);
  const camera = new PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500);
  camera.position.set(50, 50, 50);
  camera.lookAt(0, 0, 0);

  const scene = new Scene();
  const fontMaterial = new MeshBasicMaterial({
    color: 0x0000ff, //设置材质颜色
    transparent: true,//开启透明
    opacity: 0.5,//设置透明度
  });
  const material = new LineBasicMaterial({color: 0x0000ff});
  loader.load( './fonts/helvetiker_regular.typeface.json', function ( font ) {
    const geometry = new TextGeometry( 'Hello three.js!', {
      font: font,
      size: 2,
      depth: 0.5,
      curveSegments: 6,
      bevelEnabled: false,
      bevelThickness: 2,
      bevelSize: 2,
      bevelSegments: 5
    });
    const mesh = new Mesh(geometry, fontMaterial);
    mesh.position.set(0, 0, 0)
    scene.add(mesh)
  });
  const points = [];
  points.push(new Vector3(-10, 0, 0));
  points.push(new Vector3(0, 10, 0));
  points.push(new Vector3(10, 0, 0));

  const geometry = new BufferGeometry().setFromPoints(points);

  const line = new Line(geometry, material);

  const axesHelper = new AxesHelper(150);
  // 坐标轴
  scene.add(axesHelper);

  // 设置相机控件轨道控制器OrbitControls
  new OrbitControls(camera, renderer.domElement);
  // onresize 事件会在窗口被调整大小时发生
  window.onresize = function () {
    // 重置渲染器输出画布canvas尺寸
    renderer.setSize(window.innerWidth, window.innerHeight);
    // 全屏情况下：设置观察范围长宽比aspect为窗口宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
    // 但是不会每渲染一帧，就通过相机的属性计算投影矩阵(节约计算资源)
    // 如果相机的一些属性发生了变化，需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
    camera.updateProjectionMatrix();
  };

  scene.add(line);

  const animate = () => {
    if (renderer) renderer.render(scene, camera);
    requestAnimationFrame(animate);
  };
  animate();
}

onMounted(() => {
  // createBoxGeometry();
  createLine();
})
</script>

<style lang="less">
#info {
  position: absolute;
  top: 100px;
  width: 100%;
  text-align: center;
  z-index: 100;
  display: block;
  color: white;
}
</style>